home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / src.zoo / src / blit / line.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-24  |  4.2 KB  |  167 lines

  1. /*                        Copyright (c) 1988 Bellcore
  2.  *                            All Rights Reserved
  3.  *       Permission is granted to copy or use this program, EXCEPT that it
  4.  *       may not be sold for profit, the copyright notice must be reproduced
  5.  *       on copies, and credit should be given to Bellcore where it is due.
  6.  *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7.  */
  8. /*    $Header: line.C,v 4.2 88/06/30 11:40:57 sau Exp $
  9.     $Source: /tmp/mgrsrc/src/blit/RCS/line.C,v $
  10. */
  11. static char    RCSid_[] = "$Source: /tmp/mgrsrc/src/blit/RCS/line.C,v $$Revision: 4.2 $";
  12.  
  13. #include "asm.h"
  14. #include "bitmap.h"
  15.  
  16. /*  Draw a line  - Bresenham method using bit-field instructions.
  17.  *  The bitfield instructions don't buy much (<10%), but they're there.
  18.  */
  19.  
  20. bit_line(dest, x0, y0, x1, y1, func)
  21. register BITMAP *dest;                /* destination bitmap */    
  22. int x0, y0, x1, y1;            /* line coordinates */
  23. int func;                    /* set, clear, or invert */
  24.    {
  25.    register int err, rincr, rdecr, d_incr, count;
  26.    register int offset;            /* bit offset from x0,y0 */
  27.    register long *base;            /* address of x0,y0 */
  28.    int dx, dy;                /* # of pixels in x and y */
  29.    int temp;
  30.  
  31. #ifndef NOCLIP
  32.    /* clip here */
  33.  
  34. #define TOP    001
  35. #define BOTTOM    002
  36. #define LEFT    004
  37. #define RIGHT    010
  38. #define CROSS(x,y) \
  39.       (x<0 ? LEFT : x>= (dest->wide) ? RIGHT : 0) + \
  40.       (y < 0 ? TOP : y >=  (dest -> high) ? BOTTOM : 0)
  41.  
  42.       {
  43.  
  44.       /* The classic line clipping algorithm */
  45.  
  46.       int cross0 = CROSS(x0, y0);
  47.       int cross1 = CROSS(x1, y1);
  48.  
  49.       while (cross0 || cross1) {
  50.           int cross, x, y;
  51.           if (cross0 & cross1)
  52.              return;
  53.           if (cross0 != 0)
  54.              cross = cross0;
  55.           else
  56.              cross = cross1;
  57.           if (cross & (LEFT | RIGHT)) {
  58.              int edge = (cross & LEFT) ? 0 : dest->wide - 1;
  59.              y = y0 + (y1 - y0) * (edge - x0) / (x1 - x0);
  60.              x = edge;
  61.              }
  62.           else if (cross & (TOP | BOTTOM)) {
  63.              int edge = (cross & TOP) ? 0 : dest->high - 1;
  64.              x = x0 + (x1 - x0) * (edge - y0) / (y1 - y0);
  65.              y = edge;
  66.              }
  67.           if (cross == cross0) {
  68.              x0 = x;
  69.              y0 = y;
  70.              cross0 = CROSS(x, y);
  71.              }
  72.           else {
  73.              x1 = x;
  74.              y1 = y;
  75.              cross1 = CROSS(x, y);
  76.              }
  77.          }
  78.       }
  79.  
  80.    /* end of clipping */
  81. #endif
  82.  
  83.    x0 += dest->x0;
  84.    y0 += dest->y0;
  85.    x1 += dest->x0;
  86.    y1 += dest->y0;
  87.  
  88.    /* always draw left to right */
  89.  
  90.    if (x1 < x0) {
  91.       temp = x1, x1 = x0, x0 = temp;
  92.       temp = y1, y1 = y0, y0 = temp;
  93.       }
  94.    dx = x1 - x0;
  95.    dy = y1 - y0;
  96.  
  97.    if (dy > 0)
  98.       d_incr = BIT_LINE(dest);
  99.    else
  100.       d_incr = -BIT_LINE(dest), dy = -dy;
  101.  
  102.    base = y0 * (BIT_LINE(dest) >> 5) + (dest->data);    /* start of line */
  103.    offset = x0;            /* bit offset from line */
  104.  
  105. #define STEP(dx,dy,xmove,ymove,op) {        \
  106.     rincr = (dx - dy)<<1;            \
  107.     rdecr = -(dy<<1);                \
  108.     err = dx + rdecr;                \
  109.     for (count = dx; count >= 0; count--) {    \
  110.         op($base,$offset,IMM(1)); \
  111.         offset  += (xmove);                        \
  112.         if (err < 0) {                \
  113.             offset += (ymove);                \
  114.             err += rincr;                \
  115.             }                    \
  116.         else {                    \
  117.             err += rdecr;                \
  118.             }                    \
  119.         }                     \
  120.     }
  121.  
  122.    /* @+ */
  123.  
  124.    if (dx > dy)            /* gentle slope */
  125.       switch (OPCODE(func)) {
  126.      case OPCODE(SRC):
  127.      case OPCODE(SRC | DST):
  128.      case OPCODE(SRC | ~DST):
  129.      case OPCODE(~0):
  130.         STEP(dx, dy, 1, d_incr, BF_SET);
  131.         break;
  132.      case OPCODE(~SRC):
  133.      case OPCODE(~(SRC|DST)):
  134.      case OPCODE(DST & ~SRC):
  135.      case OPCODE(0):
  136.         STEP(dx, dy, 1, d_incr, BF_CLR);
  137.         break;
  138.      case OPCODE(SRC ^ DST):
  139.      case OPCODE(~DST):
  140.      case OPCODE(SRC & ~DST):
  141.      case OPCODE(~(SRC&DST)):
  142.         STEP(dx, dy, 1, d_incr, BF_INV);
  143.         break;
  144.          }
  145.    else                /* steep slope */
  146.       switch (OPCODE(func)) {
  147.      case OPCODE(SRC):
  148.      case OPCODE(SRC | DST):
  149.      case OPCODE(SRC | ~DST):
  150.      case OPCODE(~0):
  151.         STEP(dy, dx, d_incr, 1, BF_SET);
  152.         break;
  153.      case OPCODE(~SRC):
  154.      case OPCODE(~(SRC|DST)):
  155.      case OPCODE(DST & ~SRC):
  156.      case OPCODE(0):
  157.         STEP(dy, dx, d_incr, 1, BF_CLR);
  158.         break;
  159.      case OPCODE(SRC ^ DST):
  160.      case OPCODE(~DST):
  161.      case OPCODE(SRC & ~DST):
  162.      case OPCODE(~(SRC&DST)):
  163.         STEP(dy, dx, d_incr, 1, BF_INV);
  164.         break;
  165.     }
  166.    }
  167.